import AppConfig from '@/config';
import { useErrorHandler } from '@/utils/errorHandler';
import { computed, reactive, ref } from 'vue';

/**
 * 表单验证 Composable
 * @param {Object} initialData - 初始表单数据
 * @param {Object} rules - 验证规则
 * @returns {Object} 表单验证对象
 */
export function useFormValidation(initialData = {}, rules = {}) {
    const errorHandler = useErrorHandler();
    const formData = reactive({ ...initialData });
    const errors = ref({});
    const isSubmitting = ref(false);
    const touched = ref({});

    /**
     * 验证单个字段
     * @param {string} field - 字段名
     * @param {any} value - 字段值
     * @returns {string|null} 错误信息或null
     */
    const validateField = (field, value) => {
        const rule = rules[field];
        if (!rule) return null;

        // 必填验证
        if (rule.required && (!value || value.toString().trim() === '')) {
            return rule.message || '此字段为必填项';
        }

        // 如果值为空且非必填，跳过其他验证
        if (!value && !rule.required) {
            return null;
        }

        // 最小长度验证
        if (rule.min && value.toString().length < rule.min) {
            return rule.message || `最少需要${rule.min}个字符`;
        }

        // 最大长度验证
        if (rule.max && value.toString().length > rule.max) {
            return rule.message || `最多允许${rule.max}个字符`;
        }

        // 正则表达式验证
        if (rule.pattern && !rule.pattern.test(value)) {
            return rule.message || '格式不正确';
        }

        // 邮箱验证
        if (rule.type === 'email') {
            const emailPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;
            if (!emailPattern.test(value)) {
                return rule.message || '请输入有效的邮箱地址';
            }
        }

        // 数字验证
        if (rule.type === 'number') {
            const num = Number(value);
            if (isNaN(num)) {
                return rule.message || '请输入有效的数字';
            }
            if (rule.min !== undefined && num < rule.min) {
                return `数值不能小于${rule.min}`;
            }
            if (rule.max !== undefined && num > rule.max) {
                return `数值不能大于${rule.max}`;
            }
        }

        // 自定义验证函数
        if (rule.validator && typeof rule.validator === 'function') {
            return rule.validator(value, formData);
        }

        return null;
    };

    /**
     * 验证所有字段
     * @returns {boolean} 是否验证通过
     */
    const validateForm = () => {
        const newErrors = {};
        let isValid = true;

        Object.keys(rules).forEach(field => {
            const error = validateField(field, formData[field]);
            if (error) {
                newErrors[field] = error;
                isValid = false;
            }
        });

        errors.value = newErrors;
        return isValid;
    };

    /**
     * 验证特定字段
     * @param {string} field - 字段名
     */
    const validateSingleField = (field) => {
        const error = validateField(field, formData[field]);
        if (error) {
            errors.value[field] = error;
        } else {
            delete errors.value[field];
        }
        touched.value[field] = true;
    };

    /**
     * 清除验证错误
     * @param {string} field - 字段名，如果不提供则清除所有错误
     */
    const clearErrors = (field = null) => {
        if (field) {
            delete errors.value[field];
        } else {
            errors.value = {};
        }
    };

    /**
     * 重置表单
     */
    const resetForm = () => {
        Object.keys(formData).forEach(key => {
            formData[key] = initialData[key] || '';
        });
        errors.value = {};
        touched.value = {};
        isSubmitting.value = false;
    };

    /**
     * 设置字段值
     * @param {string} field - 字段名
     * @param {any} value - 字段值
     */
    const setFieldValue = (field, value) => {
        formData[field] = value;
        if (touched.value[field]) {
            validateSingleField(field);
        }
    };

    /**
     * 提交表单
     * @param {Function} submitFn - 提交函数
     * @returns {Promise} 提交结果
     */
    const handleSubmit = async (submitFn) => {
        if (isSubmitting.value) return;

        if (!validateForm()) {
            errorHandler.handleValidationError(errors.value);
            return;
        }

        isSubmitting.value = true;
        try {
            const result = await submitFn(formData);
            return result;
        } catch (error) {
            errorHandler.handleNetworkError(error, '表单提交');
            throw error;
        } finally {
            isSubmitting.value = false;
        }
    };

    // 计算属性
    const isValid = computed(() => Object.keys(errors.value).length === 0);
    const hasErrors = computed(() => Object.keys(errors.value).length > 0);
    const isDirty = computed(() => Object.keys(touched.value).length > 0);

    return {
        formData,
        errors: computed(() => errors.value),
        touched: computed(() => touched.value),
        isSubmitting: computed(() => isSubmitting.value),
        isValid,
        hasErrors,
        isDirty,
        validateField,
        validateForm,
        validateSingleField,
        clearErrors,
        resetForm,
        setFieldValue,
        handleSubmit
    };
}

/**
 * 常用验证规则
 */
export const ValidationRules = {
    required: AppConfig.validation.rules.required,
    email: AppConfig.validation.rules.email,
    phone: AppConfig.validation.rules.phone,
    password: AppConfig.validation.rules.password,

    /**
     * 确认密码验证
     * @param {string} passwordField - 密码字段名
     * @returns {Object} 验证规则
     */
    confirmPassword: (passwordField = 'password') => ({
        validator: (value, formData) => {
            if (value !== formData[passwordField]) {
                return '两次输入的密码不一致';
            }
            return null;
        }
    }),

    /**
     * 长度范围验证
     * @param {number} min - 最小长度
     * @param {number} max - 最大长度
     * @returns {Object} 验证规则
     */
    length: (min, max) => ({
        min,
        max,
        message: `长度必须在${min}-${max}个字符之间`
    }),

    /**
     * 数字范围验证
     * @param {number} min - 最小值
     * @param {number} max - 最大值
     * @returns {Object} 验证规则
     */
    numberRange: (min, max) => ({
        type: 'number',
        min,
        max,
        message: `数值必须在${min}-${max}之间`
    }),

    /**
     * 自定义正则验证
     * @param {RegExp} pattern - 正则表达式
     * @param {string} message - 错误信息
     * @returns {Object} 验证规则
     */
    pattern: (pattern, message) => ({
        pattern,
        message
    })
};
